package com.mc.wsdemo.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;

import javax.websocket.Session;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Web socket 主处理程序
 */
@Slf4j
@Component
public class MyWsHandler extends AbstractWebSocketHandler {
    private static Map<String,SessionBean> sessionBeanMap;

    private static AtomicInteger clientIdMaker;

    private static  StringBuffer stringBuffer;
    static {
        sessionBeanMap = new ConcurrentHashMap<>();
        clientIdMaker = new AtomicInteger(0);
        stringBuffer = new StringBuffer();
    }

    /**
     * 连接建立
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        super.afterConnectionEstablished(session);
        SessionBean sessionBean = new SessionBean(session, clientIdMaker.getAndIncrement());
        String sessionId = session.getId();
        sessionBeanMap.put(sessionId,sessionBean);
        Integer clientId = sessionBean.getClientId();
        log.info("连接建立:{}:{}", clientId);
        stringBuffer.append(MessageFormat.format("进入了群聊:{0}<br/>",clientId));
        sendMessage(sessionBeanMap);
    }

    private void sendMessage(Map<String,SessionBean> sessionBeanMap) throws IOException {
        Iterator<Map.Entry<String, SessionBean>> iterator = sessionBeanMap.entrySet().iterator();

        String messageInChat = stringBuffer.toString();
        TextMessage textMessage = new TextMessage(messageInChat);
        while (iterator.hasNext()){
            Map.Entry<String, SessionBean> entry = iterator.next();
            entry.getValue().getWebSocketSession().sendMessage(textMessage);
        }
    }

    /**
     * 收到消息
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        super.handleTextMessage(session, message);
        String sessionId = session.getId();
        SessionBean sessionBean = sessionBeanMap.get(sessionId);
        log.info("收到消息:{}:{}", sessionBean.getClientId(),message.getPayload());

        stringBuffer.append(MessageFormat.format("{0}:{1}<br/>",sessionBean.getClientId(),message.getPayload()));
        sendMessage(sessionBeanMap);
    }

    /**
     * 传输异常
     * @param session
     * @param exception
     * @throws Exception
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        super.handleTransportError(session, exception);

        if(session.isOpen()){
            session.close();
        }
        sessionBeanMap.remove(session.getId());
        log.info("传输异常:{}:{}",sessionBeanMap.get(session.getId()).getClientId());
    }

    /**
     * 连接关闭
     * @param session
     * @param status
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        super.afterConnectionClosed(session, status);
        String sessionId = session.getId();
        SessionBean sessionBean = sessionBeanMap.get(sessionId);
        Integer clientId = sessionBean.getClientId();
        log.info("连接关闭:{}:{}",clientId,status);
        sessionBeanMap.remove(session.getId());

        stringBuffer.append(MessageFormat.format("{0}:退出群聊<br/>", clientId ));
        sendMessage(sessionBeanMap);


    }
/*    *//**
     * 每隔2000MS=2S执行一次：每2S发送给客户端心跳消息
     *//*
    @Scheduled(fixedRate = 2000)
    public void sendMsg()   {
        Set<Map.Entry<String, SessionBean>> entries = sessionBeanMap.entrySet();
        Iterator<Map.Entry<String, SessionBean>> iterator = entries.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, SessionBean> entry = iterator.next();
            SessionBean value = entry.getValue();

            try {
                value.getWebSocketSession().sendMessage(new TextMessage("心跳！")  );
            } catch (IOException e) {
                e.printStackTrace();
            }


        }

    }*/
}
